package com.crx.springbootinit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crx.springbootinit.exception.ThrowUtils;
import com.crx.springbootinit.mapper.CommentLoveMapper;
import com.crx.springbootinit.model.dto.comment.CommentLoveDto;
import com.crx.springbootinit.model.dto.comment.CommentsLovePageDTO;
import com.crx.springbootinit.model.dto.page.PageVO;
import com.crx.springbootinit.model.entity.Comment;
import com.crx.springbootinit.model.entity.CommentLove;
import com.crx.springbootinit.model.entity.Post;
import com.crx.springbootinit.model.vo.comment.CommentLovePageVO;
import com.crx.springbootinit.model.vo.comment.CommentPageVO;
import com.crx.springbootinit.service.ICommentLoveService;
import com.crx.springbootinit.service.ICommentService;
import com.crx.springbootinit.service.IPostService;
import com.crx.springbootinit.utils.ThreadLocalUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

import static com.crx.springbootinit.common.ErrorCode.NOT_LOGIN_ERROR;
import static com.crx.springbootinit.common.ErrorCode.OPERATION_ERROR;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author author
 * @since 2024-10-21
 */
@Service
public class CommentLoveServiceImpl extends ServiceImpl<CommentLoveMapper, CommentLove> implements ICommentLoveService {
    @Autowired
    private ICommentService commentService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void giveCommentLove(CommentLoveDto commentLoveDto) {
        // 获取当前用户的 ID
        Long userId = ThreadLocalUtil.get("userId");
        if (userId == null) {
            ThrowUtils.throwIf(true, NOT_LOGIN_ERROR, "未登录！请先登录再访问该界面");
        }

        // 获取评论 ID 和点赞状态
        Long commentId = commentLoveDto.getCommentId();
        boolean isLove = commentLoveDto.getIsLove();

        // 检查评论是否存在
        Comment comment = commentService.getById(commentId);
        if (comment == null) {
            ThrowUtils.throwIf(true, OPERATION_ERROR, "评论不存在");
        }

        if (isLove) {
            // 点赞逻辑
            // 检查用户是否已经点赞过该评论
            if (isCommentLove(userId, commentId)) {
                ThrowUtils.throwIf(true, OPERATION_ERROR, "您已经点赞过该评论");
            }

            // 保存点赞数据
            CommentLove commentLove = new CommentLove();
            commentLove.setUserId(userId);
            commentLove.setCommentId(commentId);
            commentLove.setCreateTime(LocalDateTime.now());
            save(commentLove);

            // 更新评论的点赞数（使用乐观锁）
            LambdaUpdateWrapper<Comment> updateWrapper = new LambdaUpdateWrapper<Comment>()
                    .eq(Comment::getId, commentId)
                    .eq(Comment::getLoveCount, comment.getLoveCount())
                    .set(Comment::getLoveCount, comment.getLoveCount() + 1);
            if (!commentService.update(updateWrapper)) {
                ThrowUtils.throwIf(true, OPERATION_ERROR, "点赞失败，请重试");
            }

        } else {
            // 取消点赞逻辑
            // 检查用户是否已经点赞过该评论
            if (!isCommentLove(userId, commentId)) {
                ThrowUtils.throwIf(true, OPERATION_ERROR, "您尚未点赞过该评论");
            }

            // 删除点赞数据
            LambdaQueryWrapper<CommentLove> queryWrapper = new LambdaQueryWrapper<CommentLove>()
                    .eq(CommentLove::getUserId, userId)
                    .eq(CommentLove::getCommentId, commentId);
            remove(queryWrapper);

            // 更新评论的点赞数（使用乐观锁）
            LambdaUpdateWrapper<Comment> updateWrapper = new LambdaUpdateWrapper<Comment>()
                    .eq(Comment::getId, commentId)
                    .eq(Comment::getLoveCount, comment.getLoveCount())
                    .set(Comment::getLoveCount, comment.getLoveCount() - 1);
            if (!commentService.update(updateWrapper)) {
                ThrowUtils.throwIf(true, OPERATION_ERROR, "取消点赞失败，请重试");
            }
        }

    }
    @Override
    public Boolean isCommentLove(Long userId, Long commentId) {
        return lambdaQuery().eq(CommentLove::getUserId,userId).eq(CommentLove::getCommentId,commentId).count() > 0;
    }

    @Override
    public PageVO<CommentLovePageVO> queryCommentLovePage(CommentsLovePageDTO commentsLovePageDTO) {
        Page<CommentLovePageVO> page = new Page<>(commentsLovePageDTO.getPageNo(), commentsLovePageDTO.getPageSize());
        IPage<CommentLovePageVO> commentIPage=baseMapper.queryCommentLovePage(page,commentsLovePageDTO);
        PageVO<CommentLovePageVO> commentPageVO = new PageVO<>();
        commentPageVO.setList(commentIPage.getRecords());
        commentPageVO.setPages(commentIPage.getPages());
        commentPageVO.setTotal(commentIPage.getTotal());
        return commentPageVO;
    }
}
